﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Zocono.Infrastructure.Common
{
    public class JsonHelper
    {
        /// <summary>
        /// 将对象序列化为JSON格式
        /// </summary>
        /// <param name="o">对象</param>
        /// <returns>json字符串</returns>
        public static string SerializeObject(object o)
        {
            try
            {
                string json = JsonConvert.SerializeObject(o);
                return json;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 解析JSON字符串生成对象实体
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="json">json字符串(eg.{"ID":"112","Name":"石子儿"})</param>
        /// <returns>对象实体</returns>
        public static T DeserializeJsonToObject<T>(string json) where T : class
        {
            try
            {
                JsonSerializer serializer = new JsonSerializer();
                StringReader sr = new StringReader(json);
                object o = serializer.Deserialize(new JsonTextReader(sr), typeof(T));
                T t = o as T;
                return t;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 解析JSON数组生成对象实体集合
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="json">json数组字符串(eg.[{"ID":"112","Name":"石子儿"}])</param>
        /// <returns>对象实体集合</returns>
        public static List<T> DeserializeJsonToList<T>(string json) where T : class
        {
            JsonSerializer serializer = new JsonSerializer();
            StringReader sr = new StringReader(json);
            object o = serializer.Deserialize(new JsonTextReader(sr), typeof(List<T>));
            List<T> list = o as List<T>;
            return list;
        }

        /// <summary>
        /// 反序列化JSON到给定的匿名对象.
        /// </summary>
        /// <typeparam name="T">匿名对象类型</typeparam>
        /// <param name="json">json字符串</param>
        /// <param name="anonymousTypeObject">匿名对象</param>
        /// <returns>匿名对象</returns>
        public static T DeserializeAnonymousType<T>(string json, T anonymousTypeObject)
        {
            T t = JsonConvert.DeserializeAnonymousType(json, anonymousTypeObject);
            return t;
        }
        /// <summary>
        /// 字符串转JSON
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static JObject StrToJson(string str)
        {
            try
            {
                JObject js = JObject.Parse(str);
                return js;
            }
            catch
            {
                return null;
            }

        }
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="xml">xml内容</param>
        /// <returns></returns>
        public static string Deserialize(string xml)
        {
            xml = xml.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>", "");
            var doc = new XmlDocument();
            doc.LoadXml(xml);
            var json = JsonConvert.SerializeXmlNode(doc);
            return json;
        }

        /// <summary>
        /// 从json中获取对应key的value值
        /// </summary>
        /// <param name="strJson">json字符串</param>
        /// <param name="key">需要取value对应的key</param>
        /// <returns></returns>
        public static string GetJsonValue(string strJson, string key)
        {
            string strResult;
            var jsonObj = JObject.Parse(strJson);
            strResult = GetNestJsonValue(jsonObj.Children(), key);
            return strResult;
        }
        /// <summary>
        /// 迭代获取eky对应的值
        /// </summary>
        /// <param name="jToken"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetNestJsonValue(JEnumerable<JToken> jToken, string key)
        {
            var enumerator = jToken.GetEnumerator();
            while (enumerator.MoveNext())
            {
                var jc = (JToken)enumerator.Current;
                if (jc is JObject || ((JProperty)jc).Value is JObject)
                {
                    return GetNestJsonValue(jc.Children(), key);
                }
                else
                {
                    if (((JProperty)jc)?.Name == key)
                    {
                        return ((JProperty)jc)?.Value.ToString();
                    }
                }
            }
            return null;
        }
    }
}
